//
//  BuildingMapViewController.m
//  mUBB
//
//  Created by Cosmin Stirbu on 3/13/13.
//  Copyright (c) 2013 Cosmin Stirbu. All rights reserved.
//

#import "BuildingMapViewController.h"
#import "BuildingAnnotation.h"

#define MINIMUM_ZOOM_ARC 0.014 //approximately 1 miles (1 degree of arc ~= 69 miles)
#define ANNOTATION_REGION_PAD_FACTOR 1.15
#define MAX_DEGREES_ARC 360

@interface BuildingMapViewController ()

@end

@implementation BuildingMapViewController

- (id)initWithNibName:(NSString *)nibNameOrNil building:(Building *)building
{
    self = [super initWithNibName:nibNameOrNil bundle:nil];
    if (self) {
        // Custom initialization
        _building = building;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = _building.name;
    BuildingAnnotation *buildingAnnotation = [[BuildingAnnotation alloc] initWithBuilding:_building];
    [_mapView addAnnotation:buildingAnnotation];
    _mapView.delegate = self;
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([buildingAnnotation coordinate], 1500, 1500);
    [_mapView setRegion:region animated:YES];
    [_mapView selectAnnotation:buildingAnnotation animated:YES];
}

#pragma mark - Private Methods

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self zoomMapViewToFitAnnotations:_mapView animated:YES];
}

//size the mapView region to fit its annotations
- (void)zoomMapViewToFitAnnotations:(MKMapView *)mapView animated:(BOOL)animated
{
    NSMutableArray *annotations = [NSMutableArray arrayWithArray:mapView.annotations];
    if (mapView.userLocation != nil) {
        [annotations addObject:mapView.userLocation];
    }
    int count = [annotations count];
    if ( count == 0) { return; } //bail if no annotations
    
    //convert NSArray of id <MKAnnotation> into an MKCoordinateRegion that can be used to set the map size
    //can't use NSArray with MKMapPoint because MKMapPoint is not an id
    MKMapPoint points[count]; //C array of MKMapPoint struct
    for( int i=0; i<count; i++ ) //load points C array by converting coordinates to points
    {
        CLLocationCoordinate2D coordinate = [(id <MKAnnotation>)[annotations objectAtIndex:i] coordinate];
        points[i] = MKMapPointForCoordinate(coordinate);
    }
    //create MKMapRect from array of MKMapPoint
    MKMapRect mapRect = [[MKPolygon polygonWithPoints:points count:count] boundingMapRect];
    //convert MKCoordinateRegion from MKMapRect
    MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
    
    //add padding so pins aren't scrunched on the edges
    region.span.latitudeDelta  *= ANNOTATION_REGION_PAD_FACTOR;
    region.span.longitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
    //but padding can't be bigger than the world
    if( region.span.latitudeDelta > MAX_DEGREES_ARC ) { region.span.latitudeDelta  = MAX_DEGREES_ARC; }
    if( region.span.longitudeDelta > MAX_DEGREES_ARC ){ region.span.longitudeDelta = MAX_DEGREES_ARC; }
    
    //and don't zoom in stupid-close on small samples
    if( region.span.latitudeDelta  < MINIMUM_ZOOM_ARC ) { region.span.latitudeDelta  = MINIMUM_ZOOM_ARC; }
    if( region.span.longitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.longitudeDelta = MINIMUM_ZOOM_ARC; }
    //and if there is a sample of 1 we want the max zoom-in instead of max zoom-out
    if( count == 1 )
    {
        region.span.latitudeDelta = MINIMUM_ZOOM_ARC;
        region.span.longitudeDelta = MINIMUM_ZOOM_ARC;
    }
    [mapView setRegion:region animated:animated];
}

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    [self zoomMapViewToFitAnnotations:_mapView animated:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidUnload {
    _mapView = nil;
    [super viewDidUnload];
}
@end
